<#-- 此宏包含《网络请求》《vue通用设置》《实用小工具》，为引用方便集成到一个宏里 -->
<script>
    // 网络请求
    {
        var jsonService = axios.create({
            method: 'post',
            timeout: 30000,
            baseURL: '${context?default("")}',
            headers: {'Content-Type': 'application/json;charset=UTF-8'},
        });
        var downloadService = axios.create({
            method: 'post',
            timeout: 3 * 60 * 1000,
            baseURL: '${context?default("")}',
            responseType: 'blob',
            headers: {'Content-Type': 'application/json;charset=UTF-8'},
        });
        var uploadService = axios.create({
            method: 'post',
            timeout: 3 * 60 * 1000,
            baseURL: '${context?default("")}',
            headers: {'Content-Type': 'multipart/form-data'},
            onUploadProgress: function (progressEvent) {
                var complete = (progressEvent.loaded / progressEvent.total * 100 | 0) + '%'
                nav.tipShow("上传中(" + complete + ")")
                if (complete === '100%') {
                    nav.tipShow("处理中，请稍等..")
                }
            },
        });
        var importService = axios.create({
            method: 'post',
            timeout: 3 * 60 * 1000,
            baseURL: '${context?default("")}',
            responseType: 'blob',
            headers: {'Content-Type': 'multipart/form-data'},
            onUploadProgress: function (progressEvent) {
                var complete = (progressEvent.loaded / progressEvent.total * 100 | 0) + '%'
                nav.tipShow("上传中(" + complete + ")")
                if (complete === '100%') {
                    nav.tipShow("处理中，请稍等..")
                }
            },
        });
        function handleError(status) {
            switch (status) {
                case 401:
                    return {message: "未授权，请登录(401)"};
                case 403:
                    return {message: "拒绝访问(403)"};
                case 404:
                    return {message: "请求地址错误(404)"};
                case 408:
                    return {message: "请求超时(408)"};
                case 500:
                    return {message: "服务器内部错误(500)"};
                case 501:
                    return {message: "服务未实现(501)"};
                default:
                    return {message: "请求错误(" + error.response.status + ")"};
            }
        }
        function jsonRequest(data) {
            nav.barShow();
            return jsonService.request(data)
                    .then(function (response) {
                        if (response.data.errors && response.data.errors.length == 0) {
                            nav.barFinish();
                        } else if (response.data.errors && response.data.errors.length > 0) {
                            nav.barError();
                        } else {
                            response.data = {errors: [{message: '服务器响应错误'}]};
                            nav.barError();
                        }
                        return Promise.resolve(response.data);
                    }, function (error) {
                        nav.barError();
                        const rsp = {errors: []};
                        if (!error.response) {
                            rsp.errors.push({message: error.message});
                        } else {
                            rsp.errors.push(handleError(error.response.status));
                        }
                        return Promise.resolve(rsp);
                    })
        };
        function uploadRequest(data) {
            nav.barShow();
            nav.tipShow("上传中...");
            var fd = new FormData();
            fd.append("file", data.data);
            data.data = fd;
            return uploadService.request(data)
                    .then(function (response) {
                        nav.tipClose();
                        if (response.data.errors && response.data.errors.length == 0) {
                            nav.barFinish();
                        } else if (response.data.errors && response.data.errors.length > 0) {
                            nav.barError();
                        } else {
                            response.data = {errors: [{message: '服务器响应错误'}]};
                            nav.barError();
                        }
                        return Promise.resolve(response.data);
                    }, function (error) {
                        nav.barError();
                        const rsp = {errors: []};
                        if (!error.response) {
                            rsp.errors.push({message: error.message});
                        } else {
                            rsp.errors.push(handleError(error.response.status));
                        }
                        return Promise.resolve(rsp);
                    })
        };
        function importRequest(data) {
            nav.barShow();
            nav.tipShow("上传中...");
            var fd = new FormData();
            fd.append("file", data.data);
            data.data = fd;
            return importService.request(data)
                    .then(function (response) {
                        nav.tipClose();
                        if (!response.data) {
                            nav.barError();
                            return Promise.resolve({errors: [{message: '下载错误'}]});
                        } else if ("application/json" == response.data.type) {
                            var reader = new FileReader();
                            reader.addEventListener("loadend", function () {
                                var rsp = JSON.parse(reader.result);
                                if (rsp.errors.length > 0) {
                                    nav.barError();
                                    nav.e(rsp.errors[0].message)
                                } else {
                                    nav.barFinish();
                                }
                            });
                            reader.readAsText(response.data, "utf-8");
                            return Promise.resolve({errors: []});
                        } else {
                            nav.barFinish();
                            // 获取响应header中文件信息
                            var dis = response.headers['content-disposition'];
                            // 正则匹配文件名
                            var fileName = dis.match(/filename="(.*\..*)"/)[1];
                            // 模拟下载
                            utils.blobtoDown(decodeURIComponent(fileName), new Blob([response.data]))
                            return Promise.resolve({errors: []});
                        }
                    }, function (error) {
                        nav.tipClose();
                        nav.barError();
                        const rsp = {errors: []};
                        if (!error.response) {
                            rsp.errors.push({message: error.message});
                        } else {
                            rsp.errors.push(handleError(error.response.status));
                        }
                        return Promise.resolve(rsp);
                    })
        };
        function downRequest(data) {
            nav.barShow();
            return downloadService.request(data)
                    .then(function (response) {
                        if (!response.data) {
                            nav.barError();
                            return Promise.resolve({errors: [{message: '下载错误'}]});
                        } else if ("application/json" == response.data.type) {
                            var reader = new FileReader();
                            reader.addEventListener("loadend", function () {
                                var rsp = JSON.parse(reader.result);
                                if (rsp.errors.length > 0) {
                                    nav.barError();
                                    nav.e(rsp.errors[0].message)
                                } else {
                                    nav.barFinish();
                                }
                            });
                            reader.readAsText(response.data, "utf-8");
                            return Promise.resolve({errors: []});
                        } else {
                            nav.barFinish();
                            // 获取响应header中文件信息
                            var dis = response.headers['content-disposition'];
                            // 正则匹配文件名
                            var fileName = dis.match(/filename="(.*\..*)"/)[1];
                            // 模拟下载
                            utils.blobtoDown(decodeURIComponent(fileName), new Blob([response.data]))
                            return Promise.resolve({errors: []});
                        }
                    }, function (error) {
                        nav.tipClose();
                        nav.barError();
                        const rsp = {errors: []};
                        if (!error.response) {
                            rsp.errors.push({message: error.message});
                        } else {
                            rsp.errors.push(handleError(error.response.status));
                        }
                        return Promise.resolve(rsp);
                    })
        };
        function Ajax(module, target, method) {
            this.mModule = module;
            this.mTarget = target;
            this.mMethod = method;

            this.method = function (method) {
                this.mMethod = method;
                return this;
            };
            this.post = function (data, callback) {
                switch (this.mMethod) {
                    case "upload":
                        return uploadRequest({
                            url: '/ajax/' + this.mModule + "/" + this.mTarget + "/" + this.mMethod,
                            data: data
                        }).then(callback);
                        break;
                    case "imports":
                        return importRequest({
                            url: '/ajax/' + this.mModule + "/" + this.mTarget + "/" + this.mMethod,
                            data: data
                        }).then(callback);
                        break;
                    case "exports":
                        return downRequest({
                            url: '/ajax/' + this.mModule + "/" + this.mTarget + "/" + this.mMethod,
                            data: JSON.stringify(data)
                        }).then(callback)
                        break;
                    case "template":
                        return downRequest({
                            url: '/ajax/' + this.mModule + "/" + this.mTarget + "/" + this.mMethod,
                            data: JSON.stringify(data)
                        }).then(callback);
                        break;
                    default:
                        return jsonRequest({
                            url: '/ajax/' + this.mModule + "/" + this.mTarget + "/" + this.mMethod,
                            data: JSON.stringify(data)
                        }).then(callback);
                }
            };
            this.create = function (data, callback) {
                this.mMethod = "create";
                this.post(data, callback);
            };
            this.delete = function (data, callback) {
                this.mMethod = "delete";
                this.post(data, callback);
            };
            this.update = function (data, callback) {
                this.mMethod = "update";
                this.post(data, callback);
            };
            this.find = function (data, callback) {
                this.mMethod = "find";
                this.post(data, callback);
            };
            this.get = function (data, callback) {
                this.mMethod = "get";
                this.post(data, callback);
            };
            this.load = function (data, callback) {
                this.mMethod = "load";
                this.post(data, callback);
            };
            this.template = function (data, callback) {
                this.mMethod = "template";
                this.post(data, callback);
            };
            this.imports = function (data, callback) {
                this.mMethod = "imports";
                this.post(data, callback);
            };
            this.exports = function (data, callback) {
                this.mMethod = "exports";
                this.post(data, callback);
            };
            this.upload = function (data, callback) {
                this.mMethod = "upload";
                this.post(data, callback);
            };
        }
    }
    // vue通用设置
    {
        // 关闭生产提示
        Vue.config.productionTip = false;
        // 字典缓存对象
        Vue.prototype.$dictMap = {};
        // 全局提交标记
        Vue.prototype.$isSubmit = false;
        // 字典组件
        Vue.component('el-input-dict', {
            data: function () {
                return {
                    item: {},
                    options: []
                }
            },
            props: {
                value: {
                    type: String | Object,
                    default: ''
                },
                valueFor: {
                    type: String,
                    default: 'key',
                    validator: function (value) {
                        var r = (['key', 'value', 'item'].indexOf(value) !== -1);
                        if (!r) {
                            console.error("value-for的值只能是['key','value','item']中的一个.")
                        }
                        return r;
                    }
                },
                dictName: {
                    type: String,
                    default: ''
                },
                size: {
                    type: String,
                    default: 'small'
                },
                placeholder: {
                    type: String,
                    default: ''
                },
                change: {
                    type: Function,
                    default: function (item) {

                    }
                }
            },
            watch: {
                value: function (val, old) {
                    this.init();
                }
            },
            methods: {
                input: function (item) {
                    this.item = item;
                    switch (this.valueFor) {
                        case "key":
                            this.$emit('input', item.key);
                            break;
                        case "value":
                            this.$emit('input', item.value);
                            break;
                        case "item":
                            this.$emit('input', item);
                            break;
                    }
                },
                init: function () {
                    if (this.dictName) {
                        var dictItems = Vue.prototype.$dictMap[this.dictName];
                        if (typeof(dictItems) === "undefined") {
                            new Ajax("wsys", "dict", "load").post({
                                dictName: this.dictName
                            }, function (response) {
                                if (response.errors.length > 0) {
                                    console.error(response.errors[0].message)
                                } else {
                                    Vue.prototype.$dictMap[this.dictName] = response.dictItems;
                                }
                            }.bind(this));
                            Vue.prototype.$dictMap[this.dictName] = [];
                            this.init();
                        } else if (dictItems.length === 0) {
                            setTimeout(function () {
                                this.init()
                            }.bind(this), 100);
                        } else {
                            this.options = dictItems;
                            this.item = {};
                            for (var i = 0; i < this.options.length; i++) {
                                if (this.options[i].key == this.value) {
                                    this.item = this.options[i];
                                }
                            }
                        }
                    }
                }
            },
            created: function () {
                this.init();
            },
            template: '' +
            '<el-select :value="item.value" @input="input" filterable clearable placeholder="请选择" :size="size" :placeholder="placeholder" @change="change">' +
            ' <el-option v-for="item in options" :key="item.key" :label="item.value" :value="item">' +
            '  <span style="float: left">{{ item.value }}</span>' +
            '  <span style="float: right; color: #8492a6; font-size: 12px">{{ item.key }}</span>' +
            ' </el-option>' +
            '</el-select>'
        });
        // 字典组件
        Vue.component('el-view-dict', {
            data: function () {
                return {
                    item: {},
                }
            },
            props: {
                value: {
                    type: String,
                    default: ''
                },
                dictName: {
                    type: String,
                    default: ''
                },
            },
            watch: {
                value: function (val, old) {
                    this.init();
                }
            },
            methods: {
                init: function () {
                    if (this.dictName) {
                        var dictItems = Vue.prototype.$dictMap[this.dictName];
                        if (typeof(dictItems) === "undefined") {
                            new Ajax("wsys", "dict", "load").post({
                                dictName: this.dictName
                            }, function (response) {
                                if (response.errors.length > 0) {
                                    console.error(response.errors[0].message)
                                } else {
                                    Vue.prototype.$dictMap[this.dictName] = response.dictItems;
                                }
                            }.bind(this));
                            Vue.prototype.$dictMap[this.dictName] = [];
                            this.init();
                        } else if (dictItems.length === 0) {
                            setTimeout(function () {
                                this.init()
                            }.bind(this), 100);
                        } else {
                            this.options = dictItems;
                            for (var i = 0; i < this.options.length; i++) {
                                if (this.options[i].key == this.value) {
                                    this.item = this.options[i];
                                }
                            }
                        }
                    }
                }
            },
            created: function () {
                this.init();
            },
            template: '' +
            '<span>{{item.value}}</span>'
        });
        // 机构选择
        Vue.component('el-input-dept', {
            data: function () {
                return {
                    options: [],
                    props: {
                        multiple: false,
                        checkStrictly: true
                    }
                }
            },
            props: {
                value: {
                    type: String,
                    default: ''
                },
                size: {
                    type: String,
                    default: 'small'
                },
                clearable: {
                    type: Boolean,
                    default: true
                },
                placeholder: {
                    type: String,
                    default: ''
                },
            },
            methods: {
                input: function (value) {
                    this.$emit('input', value[value.length - 1]);
                }
            },
            created: function () {
                new Ajax("wsys", "dept").method("tree").post({
                    dictName: this.dictName
                }, function (response) {
                    if (response.errors.length > 0) {
                        console.error(response.errors[0].message)
                    } else {
                        this.options = response.result;
                    }
                }.bind(this))
            },
            template: '' +
            '<el-cascader  ' +
            ' :value="value" ' +
            ' @input="input" ' +
            ' :show-all-levels="false" ' +
            ' :options="options" ' +
            ' :clearable="clearable" ' +
            ' :size="size" ' +
            ' :props="props" ' +
            ' filterable ' +
            ' :placeholder="placeholder">' +
            '</el-cascader>'
        });
        // 下拉按钮
        Vue.component('wb-dropdown', {
            data: function () {
                return {
                    items: []
                }
            },
            props: {
                size: {
                    type: String,
                    default: 'mini'
                },
                type: {
                    type: String,
                    default: 'primary'
                },
                splitButton: {
                    type: Boolean,
                    default: false
                },
                arg: {
                    type: Object | String | Number,
                    default: {}
                }
            },
            methods: {
                input: function (value) {
                    this.$emit('input', value[value.length - 1]);
                },
                onCommand: function (index) {
                    if (this.items[index].click) {
                        this.items[index].click(this.arg);
                    }
                }
            },
            created: function () {
                if (this.$slots['dropdown'] && this.$slots['dropdown'].length > 0) {
                    for (var i = 0; i < this.$slots['dropdown'][0].children.length; i++) {
                        var item = this.$slots['dropdown'][0].children[i];
                        if (item.tag === 'wb-dropdown-item') {
                            var t = item.children.filter(function (item) {
                                return typeof item.tag === 'undefined';
                            });
                            this.items.push({
                                text: t[0].text,
                                icon: item.data && item.data.attrs ? item.data.attrs['icon'] : null,
                                click: item.data && item.data.on ? item.data.on['click'] : null
                            })
                        }
                    }
                }
            },
            template: '' +
            '<el-dropdown ' +
            ' :size="size" ' +
            ' :type="type" ' +
            ' :split-button="splitButton" ' +
            ' @click="onCommand(0)" ' +
            ' @command="onCommand">' +
            '<slot></slot>' +
            '  <el-dropdown-menu slot="dropdown">' +
            '    <el-dropdown-item v-for="(item,index) in items" :key="index" :command="index" :icon="item.icon">' +
            '      {{item.text}}' +
            '    </el-dropdown-item>' +
            '  </el-dropdown-menu>' +
            '</el-dropdown>'
        });
        // 表数据操作,动态操作项
        Vue.component('wb-table-ops', {
            data: function () {
                return {
                    items: []
                }
            },
            props: {
                size: {
                    type: String,
                    default: 'mini'
                },
                type: {
                    type: String,
                    default: 'primary'
                },
                splitButton: {
                    type: Boolean,
                    default: true
                },
                arg: {
                    type: Object | String | Number,
                    default: {}
                }
            },
            methods: {
                input: function (value) {
                    this.$emit('input', value[value.length - 1]);
                },
                onCommand: function (index) {
                    if (this.items[index].click) {
                        this.items[index].click(this.arg);
                    }
                }
            },
            created: function () {
                for (var i = 0; i < this.$slots.default.length; i++) {
                    var tag = this.$slots.default[i];
                    if (tag.tag === 'wb-table-op') {
                        this.items.push({
                            value: tag.data.attrs ? tag.data.attrs['value'] : "",
                            icon: tag.data.attrs ? tag.data.attrs['icon'] : "",
                            click: tag.data.on ? tag.data.on['click'] : undefined
                        })
                    }
                }
            },
            template: '' +
            '<el-dropdown ' +
            ' :size="size" ' +
            ' :type="type" ' +
            ' :split-button="splitButton" ' +
            ' @click="onCommand(0)" ' +
            ' @command="onCommand"><i :class="items[0].icon"></i>{{items[0].value}}' +
            '  <el-dropdown-menu slot="dropdown" style="white-space: nowrap">' +
            '    <el-dropdown-item v-for="(item,index) in items" :key="index" v-if="index != 0" :command="index" :icon="item.icon">' +
            '      {{item.value}}' +
            '    </el-dropdown-item>' +
            '  </el-dropdown-menu>' +
            '</el-dropdown>'
        });
        // Vue复用组件
        var mixinForMgr = {
            data: {
                //上下文
                context: '${context?default("")}',
                //列表查询存放集合
                result: [],
                //列表选择集合
                select: []
            },
            methods: {
                onSearch: function () {
                    this.vm.pageNumber = 1;
                    this.onFind();
                },
                onReset: function (form) {
                    this.$refs[form].resetFields();
                    nav.s('重置成功');
                },
                onPageChange: function (pageNumber) {
                    this.vm.pageNumber = pageNumber;
                    this.onFind();
                },
                onPageSizeChange: function (pageSize) {
                    this.vm.pageSize = pageSize;
                    this.onFind();
                },
                onSelectionChange: function (select) {
                    this.select = select;
                },
                onTemplate: function () {
                    new Ajax(this.module, this.target).method("template").post({}, function (response) {
                        if (response.errors.length > 0) {
                            nav.e(response.errors[0].message);
                        }
                    })
                },
                onImport: function (item) {
                    utils.selectFile(function (files) {
                        new Ajax(this.module, this.target).method("imports").post(files[0], function (response) {
                            if (response.errors.length > 0) {
                                nav.e(response.errors[0].message);
                            }
                        });
                    }.bind(this))
                },
                onExport: function () {
                    var req = JSON.parse(JSON.stringify(this.vm));
                    req.pageSize = 0;
                    new Ajax(this.module, this.target).method("exports").post(req, function (response) {
                        if (response.errors.length > 0) {
                            nav.e(response.errors[0].message);
                        }
                    });
                },
                onSave: function () {
                    this.$refs['form'].validate(function (valid) {
                        if (valid) {
                            if (this.form.id) {
                                new Ajax(this.module, this.target).update(this.form, function (response) {
                                    if (response.errors.length > 0) {
                                        nav.e(response.errors[0].message);
                                    } else {
                                        this.onFind();
                                        this.$refs['form'].resetFields();
                                        this.form.formShow = false;
                                    }
                                }.bind(this))
                            } else {
                                new Ajax(this.module, this.target).create(this.form, function (response) {
                                    if (response.errors.length > 0) {
                                        nav.e(response.errors[0].message);
                                    } else {
                                        this.onFind();
                                        this.$refs['form'].resetFields();
                                        this.form.formShow = false;
                                    }
                                }.bind(this))
                            }
                        } else {
                            return false;
                        }
                    }.bind(this));
                },
                onFind: function () {
                    new Ajax(this.module, this.target).find(this.vm, function (response) {
                        if (response.errors.length > 0) {
                            nav.e(response.errors[0].message);
                        } else {
                            this.result = response.result;
                            this.vm.totalCount = Number(response.totalCount);
                        }
                    }.bind(this))
                },
                onDelete: function (item) {
                    this.$confirm('将删除该项, 是否继续?', '提示', {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        type: 'warning'
                    }).then(function () {
                        new Ajax(this.module, this.target).delete({id: item.id}, function (response) {
                            if (response.errors.length > 0) {
                                nav.e(response.errors[0].message);
                            } else {
                                nav.s("删除成功");
                                this.onFind();
                            }
                        }.bind(this))
                    }.bind(this)).catch(function (action) {

                    });
                },
                onBitchDelete: function () {
                    if (this.select.length == 0) {
                        nav.w("至少选中一项");
                    } else {
                        this.$confirm('将删除已选择的项, 是否继续?', '提示', {
                            confirmButtonText: '确定',
                            cancelButtonText: '取消',
                            type: 'warning'
                        }).then(function () {
                            nav.tipShow("删除中...");
                            this.select.forAsync(function (item, next) {
                                new Ajax(this.module, this.target).delete({id: item.id}, function (response) {
                                    if (response.errors.length > 0) {
                                        nav.e(response.errors[0].message);
                                    } else {
                                        this.result.remove(item)
                                    }
                                    next();
                                }.bind(this))
                            }.bind(this), function () {
                                nav.tipClose();
                                nav.i("批量删除结束.")
                                this.onFind();
                            }.bind(this))
                        }.bind(this)).catch(function (action) {

                        });
                    }
                }
            },
            created: function () {
            },
            mounted: function () {
            },
            filters: {},
            watch: {}
        };
    }
    // 实用小工具
    {
        window.nav = new Vue({
            data: {
                loadingTip: '',
                loadingBar: '',
                context: '${context?default("")}',
            },
            methods: {
                tipShow: function (msg) {
                    var message = "<i class='el-icon-loading'></i> 正在加载 ..."
                    if (msg) {
                        message = "<i class='el-icon-loading'></i> " + msg
                    }
                    if (!this.loadingTip) {
                        this.loadingTip = this.$message({
                            type: '',
                            duration: 0,
                            dangerouslyUseHTMLString: true,
                            message: message
                        });
                    } else {
                        this.loadingTip.message = message;
                    }
                },
                tipClose: function (msg) {
                    if (this.loadingTip) {
                        this.loadingTip.close();
                        this.loadingTip = '';
                    }
                },
                barShow: function () {
                    if (window.index) {
                        window.index.barStart();
                    } else if (window.parent.index) {
                        window.parent.index.barStart();
                    }
                },
                barFinish: function () {
                    if (window.index) {
                        window.index.barFinish();
                    } else if (window.parent.index) {
                        window.parent.index.barFinish();
                    }
                },
                barError: function () {
                    if (window.index) {
                        window.index.barError();
                    } else if (window.parent.index) {
                        window.parent.index.barError();
                    }
                },
                i: function (message, callback) {
                    this.$message({
                        type: "info",
                        showClose: true,
                        message: message,
                        duration: 1500,
                        onClose: callback
                    });
                },
                e: function (message, callback) {
                    this.$message({
                        type: "error",
                        showClose: true,
                        message: message,
                        duration: 1500,
                        onClose: callback
                    });
                },
                w: function (message, callback) {
                    this.$message({
                        type: "warning",
                        showClose: true,
                        message: message,
                        duration: 1500,
                        onClose: callback
                    });
                },
                s: function (message, callback) {
                    this.$message({
                        type: "success",
                        showClose: true,
                        message: message,
                        duration: 1500,
                        onClose: callback
                    });
                },
                boxYes: function (title, message, callback) {
                    this.$alert(message, title, {
                        confirmButtonText: '确定'
                    }).then(function () {
                        callback ? callback(true) : '';
                    }).catch(function () {
                        callback ? callback(false) : '';
                    });
                },
                boxYesNo: function (title, message, callback) {
                    this.$confirm(message, title, {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消'
                    }).then(function () {
                        callback ? callback(true) : '';
                    }).catch(function () {
                        callback ? callback(false) : '';
                    });
                },
                boxInput: function (title, message, callback) {
                    this.$prompt(message, title, {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消'
                    }).then(function (value) {
                        callback ? callback(value.value) : '';
                    }).catch(function () {

                    });
                },
                boxHtml: function (title, html) {
                    this.$alert(html, title, {
                        dangerouslyUseHTMLString: true
                    });
                },
                // 本标签打开
                toOpen: function (url) {
                    window.location.open(url)
                },
                // 新标签打开
                toOpenNew: function (url) {
                    window.location.openNew(url)
                },
                // 回到首页
                toHome: function () {
                    this.tipShow();
                    location.href = this.context + "/"
                },
                // 打开一个新Tab
                tabOpen: function (tab) {
                    if (window.index) {
                        window.index.addTab(tab)
                    } else if (window.parent.index) {
                        window.parent.index.addTab(tab)
                    }
                },
                // 关闭Tab
                tabClose: function (tabName) {
                    if (window.index) {
                        window.index.removeTab(tabName)
                    } else if (window.parent.index) {
                        window.parent.index.removeTab(tabName)
                    }
                },
                // 关闭当前Tab
                tabCloseCur: function () {
                    if (window.index) {
                        window.index.removeTab(window.index.activeTabName)
                    } else if (window.parent.index) {
                        window.parent.index.removeTab(window.parent.index.activeTabName)
                    }
                },
                // 全屏
                screenFull: function () {
                    if (window.isFull)return;
                    window.isFull = true;
                    var docElm = document.documentElement;
                    // 如果首次全屏是程序发起而不是用户发起，则会出现fullscreen error
                    if (docElm.requestFullscreen) {//W3C
                        docElm.requestFullscreen();
                    } else if (docElm.mozRequestFullScreen) {//FireFox
                        docElm.mozRequestFullScreen();
                    } else if (docElm.webkitRequestFullScreen) {//Chrome等
                        docElm.webkitRequestFullScreen();
                    } else if (elem.msRequestFullscreen) {//IE11
                        elem.msRequestFullscreen();
                    } else if (typeof window.ActiveXObject !== "undefined") {
                        //for IE，这里其实就是模拟了按下键盘的F11，使浏览器全屏
                        var wscript = new ActiveXObject("WScript.Shell");
                        if (wscript != null) {
                            wscript.SendKeys("{F11}");
                        }
                    }
                },
                // 取消全屏
                screenNotFull: function () {
                    if (!window.isFull)return;
                    window.isFull = false;
                    if (document.exitFullscreen) {//W3C
                        document.exitFullscreen();
                    } else if (document.mozCancelFullScreen) {//FireFox
                        document.mozCancelFullScreen();
                    } else if (document.webkitCancelFullScreen) {//Chrome等
                        document.webkitCancelFullScreen();
                    } else if (document.msExitFullscreen) {//IE11
                        document.msExitFullscreen();
                    } else if (typeof window.ActiveXObject !== "undefined") {
                        //for IE，这里和fullScreen相同，模拟按下F11键退出全屏
                        var wscript = new ActiveXObject("WScript.Shell");
                        if (wscript != null) {
                            wscript.SendKeys("{F11}");
                        }
                    }
                },
                // 添加Cookie,expiretime可选
                setCookie: function (name, value, expiretime) {
                    if (typeof expiretime == 'undefined') {
                        document.cookie = name + "=" + encodeURIComponent(value) + ";path=/";
                    } else {
                        var exdate = new Date();
                        exdate.setDate(exdate.getTime() + expiretime);
                        document.cookie = name + "=" + encodeURIComponent(value) + ";expires=" + exdate.toGMTString() + ";path=/";
                    }
                },
                // 获取Cookie
                getCookie: function (name) {
                    var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
                    if (arr = document.cookie.match(reg)) {
                        return decodeURIComponent(arr[2]);
                    } else {
                        return "";
                    }
                },
                // 删除Cookie
                clearCookie: function (name) {
                    this.setCookie(name, "", -1);
                }
            }
        });
    }

</script>